// 1 、显示定义变量类类型
// TypeScript 的最大特性就是增加了静态类型系统。在 TypeScript 中，开发者可以显式地声明变量、参数、返回值的类型，这样可以在编译时捕获很多潜在的类型错误。
// 常见类型包括 number、string、boolean、array、tuple、enum 等，此外也支持自定义类型。
let message : string = "Hello World";
console.log( message );

// 2、隐式定义变量类型 TS会自动推断变量类型
// TypeScript 可以自动推断变量类型，即使不显式声明类型，TypeScript 也会根据变量的赋值内容来推断类型，从而在大多数情况下减少类型注解的书写量。
let PersonName = "John";
console.log( PersonName );

//3、类型别名
//类型别名 (type) 可以为复杂的类型定义简短的别名，便于代码复用。
type StringOrNumber = string | number;
let value : StringOrNumber = 123;//类型别名的使用
console.log(value );

// 4、元组类型
// 元组允许定义具有固定数量和类型的数组。它适用于需要固定数据结构的场景，比如坐标或 RGB 颜色值。
let point : [number, number] = [10, 20];
console.log(point);

// 5、 枚举类型
// TypeScript 引入了 enum 类型，用于定义一组命名的常量，提高代码的可读性。枚举在 JavaScript 中没有直接的对应。
enum Gender {
    Female = "女",
    Male = "男",
}


// 6、定义接口
// TypeScript 提供了接口，允许定义复杂的对象结构。接口可以定义属性和方法，还可以通过 implements 关键字实现接口，或者通过 extends 进行扩展，便于定义复杂的数据类型。
interface Person {
    name : string;
    age : number;
    greet: (message: string) => void;
    gender : Gender,
}

//7、 接口的实现
class Student implements Person {
    name : string;
    age : number;
    gender : Gender;

    /**
     * 构造函数
     * 用于初始化新创建的对象
     *
     * @param name 人物的姓名
     * @param age 人物的年龄
     * @param gender 人物的性别
     */
    constructor(name: string, age: number, gender: Gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    /**
     * 打招呼
     * @param message
     */
    greet(message: string): void {
        console.log(message);
    }
}

let Json = new Student("John", 20, Gender.Male);
Json.greet("I'm Json");
console.log(Json);

// 8、 访问修饰符
// TypeScript 在类中提供了 public、private 和 protected 修饰符，允许控制属性或方法的可见性，支持更好的封装。
class Teacher {
    public name : string;
    protected age : number;
    protected gender : Gender;

    /**
     * 构造函数
     * 用于初始化新创建的对象
     *
     * @param name 人物的姓名
     * @param age 人物的年龄
     * @param gender
     */
    public constructor(name: string, age: number,  gender: Gender ) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    public greet(message: string): void {
        console.log(message);
    }
}
let teacher = new Teacher("Alice", 20, Gender.Female);
teacher.greet("I'm Teacher");
console.log(teacher);

// 9、 抽象类
//TypeScript 支持抽象类，抽象类不能直接实例化，需要由子类实现。抽象类适用于定义通用行为和抽象方法的类层次结构。
abstract class Animal {
    abstract name : string;
    abstract  makeSound() : void;
}

class Dog extends Animal {
    name : string = "" ;
    constructor(name : string) {
        super();
        this.name = name;
    }
    makeSound() {
        console.log(this.name ,"汪汪汪");
    }
}

let wangCai = new Dog('旺财');
wangCai.makeSound();


// 10、泛型
//TypeScript 支持泛型，允许在类、接口和函数中使用参数化类型，使得代码可以适应不同的类型需求，同时保持类型安全。
/**
 * 泛型函数
 * @param arg
 */
function identity<T>(arg: T): T {
    return arg;
}
let output = identity<string>("myString");
let num = identity<number>(100);
console.log(output, num);

// 11、模块和命名空间
// TypeScript 提供了基于 ES6 的模块系统，使用 import 和 export 导入和导出模块。
// 此外，TypeScript 还支持命名空间（Namespace），用于组织代码和避免命名冲突。
import { average, sum } from "./math";

let total = sum( 10, 20 ),
    avg = average( 10, 20, 30, 40 );
console.log( total, avg );

// 12、类型守卫
//TypeScript 提供了类型守卫，可以在代码中检查变量类型，帮助编译器推断更加具体的类型。这对于联合类型尤为重要。
/**
 * 类型守卫
 * @param id
 */
function printId(id : string | number) {
    if (typeof id === "string") {
        console.log("string id: " + id.toUpperCase());
    } else {
        console.log("number id: " + id.toFixed(2));
    }
}
let id = "abc";
printId(id)

// 13、可选链和空值合并运算符
// TypeScript 增加了 JavaScript 的可选链 (?.) 和空值合并运算符 (??)，简化了代码中对可能为 null 或 undefined 值的处理。
let user = {
    name: "Alice",
    address: {
        city: "北京"
    },
};
console.log(user?.name);
console.log(user?.address?.city);
let defaultValue = null;
console.log(defaultValue ?? "默认值");

// 14、类型别名和接口
// TypeScript 提供了一些工具类型，如 Partial、Pick、Readonly、Record 等，这些类型可以帮助生成新的类型，简化类型定义。
interface Todo {
    title: string;
    description: string;
}
let partialTodo : Partial<Todo> = {
    title: "learn TypeScript",
    // 可选属性
    // description : "write a description",
};
console.log(partialTodo);

// 15、编译期错误检查
// TypeScript 提供的编译期错误检查可以捕获 JavaScript 中不易发现的错误，如拼写错误、类型不匹配等，帮助提升代码质量。


// 16、ES新特性支持
// TypeScript 提前支持了一些还未在所有环境中普及的 ES 特性，如装饰器（Decorators）、异步迭代器等，且能够将其编译成兼容 JavaScript 版本。